<?php
/**
 * Created by PhpStorm.
 * User: Steven
 * Date: 2017/6/19
 */

namespace app\course\controller;


use app\classes\model\ClassModel;
use app\course\model\CourseAdjustModel;
use app\course\model\CourseModel;
use app\course\model\CourseScheduleModel;
use app\system\model\SchoolModel;
use cmf\controller\AdminBaseController;
use think\Db;
use think\Exception;
use think\Log;

class CourseScheduleController extends AdminBaseController
{
    public function index()
    {
        $param = $this->request->param();
        $limit = config('limit_per_page');
        $classes = [];
        $class_mdl = new ClassModel();
        $school_mdl = new SchoolModel();
        $course_mdl = new CourseModel();
        $where = [
            'cl.shop_id' => ['=', $this->admin_shop_id],
        ];

        if (!empty($param['school_id']) && is_numeric($param['school_id'])) {
            //学校
            $where['cl.school_id'] = intval($param['school_id']);
            //获取班级
            $class = Db::name('class')
                ->where('shop_id', '=', $this->admin_shop_id)
                ->where('delete_time', '=', 0)
                ->where('school_id', '=', intval($param['school_id']))
                ->field('id,name')
                ->select();
            if (!$class->isEmpty()) {
                $classes = $class;
            }

            if (!empty($param['class_id']) && is_numeric($param['class_id'])) {
                //班级
                $where['crs.class_id'] = intval($param['class_id']);
            }
        }

        if (!empty($param['course_id']) && intval($param['course_id']) != -1) {
            //课程
            $where['cl.course_id'] = intval($param['course_id']);
        }

        if (!empty($param['start']) && !empty($param['end'])) {
            //上课日期
            $start = strtotime($param['start']);
            $end = strtotime('+23 hours 59 minutes 59 seconds', strtotime($param['end']));
            $where['crs.date'] = [['>= time', $start], ['<= time', $end]];
        } else {
            if (!empty($param['start'])) {
                $where['crs.date'] = ['>= time', strtotime($param['start'])];
            }
            if (!empty($param['end'])) {
                $end = strtotime('+23 hours 59 minutes 59 seconds', strtotime($param['end']));
                $where['crs.date'] = ['<= time', $end];
            }
        }

        $page_query = [
            'school_id' => isset($param['school_id']) ? $param['school_id'] : '',
            'class_id' => isset($param['class_id']) ? $param['class_id'] : '',
            'course_id' => isset($param['course_id']) ? $param['course_id'] : '',
            'start' => isset($param['start']) ? $param['start'] : '',
            'end' => isset($param['end']) ? $param['end'] : '',
        ];

        //排序
        $sort = ['crs.date'=>'asc'];
        $schedule_mdl = new CourseScheduleModel();
        $data = $schedule_mdl->getSchedule($where, $sort, $limit, $page_query);

        $schools = $school_mdl->getAllSchool($this->admin_shop_id);
        $courses = $course_mdl->getAllCourse($this->admin_shop_id);

        $this->assign('param', $param);
        $this->assign('schedule', $data);
        $this->assign('school', $schools);
        $this->assign('classes', $classes);
        $this->assign('course', $courses);
        $this->assign('page', $data->render());

        return $this->fetch();
    }

    /**
     * 获取班级
     * @return \think\response\Json
     */
    public function ajax_class()
    {
        if ($this->request->isPost()) {
            $param = $this->request->post();
            if (empty($param['school_id'])) {
                $json_data = [
                    'code' => 0,
                    'msg' => '校区ID不能为空',
                    'data' => []
                ];
                return json($json_data);
            }
            $data = Db::name('class')->where('delete_time', '=', 0)
                ->where('school_id', '=', intval($param['school_id']))
                ->field('id,name')->select();

            if ($data->isEmpty()) {
                $json_data = [
                    'code' => 0,
                    'msg' => '没有更多数据',
                    'school_id' => $param['school_id'],
                    'data' => $data
                ];
                return json($json_data);
            }

            $json_data = [
                'code' => 1,
                'msg' => 'success',
                'school_id' => $param['school_id'],
                'data' => $data
            ];
            return json($json_data);
        }
    }

    /**
     * 通过学校获取教室
     * @return \think\response\Json
     */
    public function ajax_classroom()
    {
        $param = $this->request->post();
        if (empty($param['school_id'])) {
            $json_data = [
                'code' => 0,
                'msg' => '学校不能为空',
                'data' => []
            ];
            return json($json_data);
        }
        //获取教室
        $data = Db::name('classroom')->where('delete_time', '=', 0)
            ->where('shop_id', '=', $this->admin_shop_id)
            ->where('school_id', '=', intval($param['school_id']))
            ->field('id,name')
            ->select();

        if ($data->isEmpty()) {
            $json_data = [
                'code' => 0,
                'msg' => '没有更多数据',
                'school_id' => $param['school_id'],
                'data' => $data
            ];
            return json($json_data);
        }else{
            $json_data = [
                'code' => 1,
                'msg' => 'success',
                'school_id' => $param['school_id'],
                'data' => $data
            ];
            return json($json_data);
        }
    }

    /**
     * 通过班级筛选课程
     * @return \think\response\Json
     */
    public function ajax_course()
    {
        $param = $this->request->post();

        if (empty($param['class_id'])) {
            $json_data = [
                'code' => 0,
                'msg' => '班级不能为空',
                'data' => []
            ];
            return json($json_data);
        }

        //获取班级
        $course = Db::name('class')->alias('cl')
            ->join('course cr', 'cl.course_id=cr.id')
            ->where('cl.shop_id', '=', $this->admin_shop_id)
            ->where('cl.delete_time', '=', 0)
            ->where('cl.id', '=', $param['class_id'])
            ->field('cl.course_id,cr.course_name')
            ->find();
        if (count($course) <= 0) {
            $json_data = [
                'code' => 0,
                'msg' => '没有更多数据',
                'class_id' => $param['class_id'],
                'data' => []
            ];
            return json($json_data);
        }

        $json_data = [
            'code' => 1,
            'msg' => 'success',
            'class_id' => $param['class_id'],
            'data' => $course
        ];
        return json($json_data);
    }

    /**
     * 调课
     * @return mixed
     */
    public function adjustSchedule()
    {
        $param = $this->request->param();
        $limit = config('limit_per_page');
        $classes = [];
        $school_mdl = new SchoolModel();
        $course_mdl = new CourseModel();
        $where = [
            'cl.shop_id' => ['=', $this->admin_shop_id],
        ];

        if (!empty($param['school_id']) && is_numeric($param['school_id'])) {
            //学校
            $where['cl.school_id'] = intval($param['school_id']);
            //获取班级
            $class = Db::name('class')
                ->where('shop_id', '=', $this->admin_shop_id)
                ->where('delete_time', '=', 0)
                ->where('school_id', '=', intval($param['school_id']))
                ->field('id,name')
                ->select();
            if (!$class->isEmpty()) {
                $classes = $class;
            }

            if (!empty($param['class_id']) && is_numeric($param['class_id'])) {
                //班级
                $where['ca.class_id'] = intval($param['class_id']);
            }
        }

        if (!empty($param['course_id']) && intval($param['course_id']) != -1) {
            //课程
            $where['cl.course_id'] = intval($param['course_id']);
        }


        $page_query = [
            'school_id' => isset($param['school_id']) ? $param['school_id'] : '',
            'class_id' => isset($param['class_id']) ? $param['class_id'] : '',
            'course_id' => isset($param['course_id']) ? $param['course_id'] : '',
        ];

        $adjust_mdl = new CourseAdjustModel();
        $data = $adjust_mdl->getAdjust($where, [], $limit, $page_query);

        $schools = $school_mdl->getAllSchool($this->admin_shop_id);
        $courses = $course_mdl->getAllCourse($this->admin_shop_id);

        $this->assign('param', $param);
        $this->assign('adjust', $data);
        $this->assign('school', $schools);
        $this->assign('classes', $classes);
        $this->assign('course', $courses);
        $this->assign('page', $data->render());

        return $this->fetch();
    }

    /*
     * 添加手动排课
     */
    public function add()
    {
        //获取校区
        $school_mdl = new SchoolModel();
        $schools = $school_mdl->getAllSchool($this->admin_shop_id);

        $this->assign('schools', $schools);
        return $this->fetch();
    }

    /**
     * 保存手动排课
     */
    public function addPost()
    {
        $cur_time = time();
        $validate = validate('CourseSchedule');
        if ($this->request->isPost()) {
            $param = $this->request->except('course');

            if (!$validate->check($param)) {
                $this->error($validate->getError());
            }

            if(empty($param['school_id'])){
                $this->error('学校不能为空');
            }
            if(empty($param['class_id'])){
                $this->error('班级不能为空');
            }
            //开始时间
            $start_date = strtotime($param['start_date']);
            //结束时间
            $end_date = strtotime($param['end_date']);
            if($end_date < $start_date){
                $this->error('结束时间不能小于开始时间');
            }

            //调课
            $adjust_mdl = new CourseAdjustModel();
            $total = $adjust_mdl->where(['class_id' => $param['class_id']])->count();
            if (isset($total) && $total >= 1) {
                $this->error('该调课已存在');
            }

            $data['class_id'] = $param['class_id'];
            $data['start_date'] = $start_date;
            $data['end_date'] = $end_date;

            //添加调课
            $id = $adjust_mdl->allowField(true)->insertGetId($data);
            if ($id) {
                //获取班级
                $class = $adjust_mdl->alias('ca')
                    ->field('cl.id,cl.name,cl.classroom_id,cl.teacher_id')
                    ->join('class cl','ca.class_id=cl.id')
                    ->where('ca.id', $id)
                    ->find();

                $schedule_mdl = new CourseScheduleModel();
                //删除原有排课
                $schedule_mdl->where('class_id', '=', $class['id'])
                    ->where('schedule', '>', 0)//非临时加课
                    ->delete();
                //调课时间
                $adjust_date[0] = $start_date;
                $adjust_date[1] = $end_date;
                //获取排课
                $class_mdl = new ClassModel();
                $schedules = $class_mdl->getCourseTime($class['id'],0,0,$this->admin_shop_id,$adjust_date);
                //重新排课
                $schedule_total = count($schedules);
                if($schedule_total > 0){
                    $new_data = [];
                    foreach ($schedules as $k=>$v){
                        $new_data[$k]['class_id'] = $v['class_id'];
                        $new_data[$k]['classroom_id'] = $v['classroom_id'];
                        $new_data[$k]['teacher_id'] = $v['teacher_id'];
                        $new_data[$k]['date'] = strtotime($v['date']);
                        $new_data[$k]['start_time'] = $v['start_time'];
                        $new_data[$k]['end_time'] = $v['end_time'];
                        $new_data[$k]['week'] = $v['cur_week'];
                        $new_data[$k]['schedule'] = $v['schedule'];
                    }
                    $result = $schedule_mdl->addSchedule($new_data);
                    if(!$result){
                        //删除该调课
                        $adjust_mdl->deleteAdjust($id, $cur_time);
                        $this->error("排课出错，添加失败");
                    }
                }

                //记录日志
                $pk = $id; //主键
                $table = 'course_adjust,course_schedule';//数据表名
                $content = lang('ADD_ADJUST', ['name' => $class['name']]);
                do_log($content, $pk, $table, $cur_time);

                $this->success('添加成功', 'CourseSchedule/adjustSchedule', '', 2);
            } else {
                $this->error("添加失败");
            }
        }
    }

    /**
     * 加课或调课
     * @return \think\response\Json
     */
    public function addCourseSchedule()
    {
        $param = $this->request->post();
        if(!isset($param['is_adjust']) || empty($param['is_adjust']) || !is_numeric($param['is_adjust'])){
            //加课和调课标记
            $json_data = [
                'Message' => '添加课时类型不能为空',
                'Status' => 0,
            ];
            return json($json_data);
        }

        $is_adjust = $param['is_adjust'];
        if($is_adjust != 1 && $is_adjust != 2){
            $json_data = [
                'Message' => '添加课时类型有误',
                'Status' => 0,
            ];
            return json($json_data);
        }

        //中文星期
        $gb_week = [
            '1' => '周一','2' => '周二','3' => '周三','4' => '周四',
            '5' => '周五','6' => '周六','7' => '周日',
        ];
        $datetime = [];//课时
        $msg = '';//提示信息
        $class_mdl = new ClassModel();
        $schedule_mdl = new CourseScheduleModel();

        $class_id = $param['schedule_class'];
        if(empty($class_id)){
            $json_data = [
                'Message' => '班级不能为空',
                'Status' => 0,
            ];
            return json($json_data);
        }

        $classroom_id = $param['classroom_id'];//教室
        $teacher_id = $param['teacher_id'];//老师
        $date = $param['schedule_date'];//上课日期
        $start_time = $param['schedule_time_start'];//上课开始时间
        $end_time = $param['schedule_time_end'];//上课结束时间

        $date_total = count($date);
        $start_time_total = count($start_time);
        $end_time_total = count($end_time);
        if($date_total <= 1){
            //没有添加日期和时间段
            $json_data = [
                'Message' => '请先选择日期和时间段',
                'Status' => 0,
            ];
            return json($json_data);
        }
        if( ($date_total != $start_time_total) || ($date_total != $end_time_total) || ($start_time_total != $end_time_total) ){
            //日期和时间段不一致
            $json_data = [
                'Message' => '请重新选择日期和时间段',
                'Status' => 0,
            ];
            return json($json_data);
        }
        //移除数组首个单元
        array_shift($date);
        array_shift($start_time);
        array_shift($end_time);
        $new_date_total = count($date);
        for($k=0; $k<$new_date_total; $k++){
            $datetime[$k] = [
                'date' => strtotime($date[$k]),
                'start_time' => $start_time[$k],
                'end_time' => $end_time[$k],
            ];
        }

        //获取班级
        $cur_class = $class_mdl->where('id',intval($class_id))->find();
        if(empty($classroom_id)){
            $classroom_id = $cur_class['classroom_id'];
        }
        if(empty($teacher_id)){
            $teacher_id = $cur_class['teacher_id'];
        }

        //开启事务
        Db::startTrans();
        try {
            if($is_adjust == 1){
                /***** 加课 ******/
                //检查排课
                for($i=0; $i<$new_date_total; $i++){
                    $date_timestamp = strtotime($date[$i]);
                    //获取该班级排课开始时间(若日期相同则按开始时间升序)
                    $min_date = $schedule_mdl->where('class_id', '=', $class_id)
                        ->order(['date'=>'asc','start_time'=>'asc'])->find();
                    if( ($date_timestamp < $min_date['date']) || ($date_timestamp < time()) ){
                        $json_data = [
                            'Message' => '日期不能小于开课时间和今日时间',
                            'Status' => 0,
                        ];
                        return json($json_data);
                    }

                    $schedule = $schedule_mdl->where('class_id', '=',$class_id)
                        ->where('classroom_id', '=',$classroom_id)
                        ->where('teacher_id', '=',$teacher_id)
                        ->where('date', '=',$date_timestamp)
                        ->where('start_time', '=',$start_time[$i])
                        ->where('end_time', '=',$end_time[$i])
                        ->find();
                    if(isset($schedule['id']) && !empty($schedule['id'])) {
                        //已存在
                        continue;
                    }else{
                        //周几
                        $week_num = date('N', strtotime($date[$i]));
                        //新增调课
                        $data['class_id'] = $class_id;
                        $data['classroom_id'] = $classroom_id;
                        $data['teacher_id'] = $teacher_id;
                        $data['date'] = $date_timestamp;
                        $data['start_time'] = $start_time[$i];
                        $data['end_time'] = $end_time[$i];
                        $data['week'] = $gb_week[$week_num];
                        $data['schedule'] = 0;
                        //添加课时
                        $schedule_mdl->insert($data);
                    }
                }
            }else{
                /***** 调课(总课时数不增加) ******/
                $result = $schedule_mdl->adjustCourse($class_id,$teacher_id,$classroom_id,$datetime,$msg);
                if(!$result){
                    \exception('调课失败');
                }
            }

            Db::commit();

        }catch (Exception $e) {
            Db::rollback();

            $json_data = [
                'Message' => $msg,
                'Status' => 0,
            ];
            return json($json_data);
        }

        $json_data = [
            'Message' => '操作成功',
            'Status' => 1,
        ];
        return json($json_data);
    }

    /**
     * 删除临时加课
     */
    public function deleteSchedule()
    {
        $cur_time = time();
        $table = 'course_schedule';
        $schedule_mdl = new CourseScheduleModel();

        $param = $this->request->param();
        if (isset($param['id'])) {
            $id = $this->request->param('id', 0, 'intval');
            //获取班级
            $class_name = $schedule_mdl->alias('cs')
                ->join('class cl','cs.class_id=cl.id')
                ->where('cs.id', $id)
                ->value('cl.name');
            //记录日志
            $pk = $id;
            $content = lang('DELETE_TEMPORARY_SCHEDULE', ['name' => $class_name]);

        } else {
            $id = $this->request->param('ids/a');
            //记录日志
            $pk = implode(',', $id);
            $content = lang('BATCH_DELETE', ['name' => '排课']);
        }

        $result = $schedule_mdl->deleteSchedule($id, $cur_time);
        if ($result) {
            do_log($content, $pk, $table, $cur_time);

            $this->success("删除成功！");
        } else {
            $this->error('删除失败！');
        }
    }

    /*
     * 删除调课
     */
    public function delete()
    {
        $cur_time = time();
        $table = 'course_adjust,course_schedule';
        $adjust_mdl = new CourseAdjustModel();

        $param = $this->request->param();
        if (isset($param['id'])) {
            $id = $this->request->param('id', 0, 'intval');
            //获取班级
            $class_name = $adjust_mdl->alias('ca')
                ->join('class cl','ca.class_id=cl.id')
                ->where('ca.id', $id)
                ->value('cl.name');
            //记录日志
            $pk = $id;
            $content = lang('DELETE_ADJUST', ['name' => $class_name]);

        } else {
            $id = $this->request->param('ids/a');
            //记录日志
            $pk = implode(',', $id);
            $content = lang('BATCH_DELETE', ['name' => '调课']);
        }

        $result = $adjust_mdl->deleteAdjust($id, $cur_time);
        if ($result) {
            do_log($content, $pk, $table, $cur_time);

            $this->success("删除成功！");
        } else {
            $this->error('删除失败！');
        }
    }


    public function checkHoliday($date_timestamp)
    {
        //假期
        $holiday = Db::name('holiday')->field(['id','name','date'])
            ->where('shop_id', '=', $this->admin_shop_id)
            ->where('date', '=', $date_timestamp)
            ->find();

        return $holiday;
    }

}